const { Controller } = require('egg');

class UserController extends Controller {
    /**
     * 注册
     */
    async register() {
        // 解构参数
        const { username, password, relname } = this.ctx.request.body;

        // 非空校验
        if (!username || !password || !relname) {
            this.ctx.body = {
                code: 400,
                message: '缺少必须参数',
            };
            return;
        }

        // 用户名长度校验
        if (!/^[a-zA-Z0-9_]{5,20}$/.test(username)) {
            this.ctx.body = {
                code: 400,
                message: '用户名必须是 5 ~ 20 位字母数字下划线组合',
            };
            return;
        }

        // 密码长度校验
        if (!/^[^\W]{4,6}/.test(password)) {
            this.ctx.body = {
                code: 400,
                message: '密码必须是 4 ~ 6 位的有效字符',
            };
            return;
        }

        // 用户唯一性校验(去重)
        let user = await this.service.user.readByUsername(username);
        if (user) {
            this.ctx.body = {
                code: 403,
                message: '用户已存在，不允许重复创建',
            };
            return;
        }

        // 创建用户
        let res = await this.service.user.create({
            username,
            password: this.ctx.helper.passwordEncoder(password),
            relname,
        });

        // 判断是否创建成功
        if (res.affectedRows !== 1) {
            this.ctx.body = {
                code: 500,
                message: '用户注册失败，请稍后再试',
            };
            return;
        }

        // 注册进来的都是学生
        res = await this.service.user.saveRole(res.insertId, 3);

        // 判断是否插入成功
        if (res.affectedRows !== 1) {
            this.ctx.body = {
                code: 500,
                message: '角色生成失败，请联系管理员',
            };
            return;
        }

        // 注册成功
        this.ctx.body = {
            code: 200,
            message: '注册成功！',
        };
    }

    /**
     * 登录
     */
    async login() {
        // 解构参数
        const { username, password } = this.ctx.request.body;

        // 非空校验
        if (!username || !password) {
            this.ctx.body = {
                code: 400,
                message: '用户或密码不能为空',
            };
            return;
        }

        // 根据用户名，查询用户
        let user = await this.service.user.readByUsername(username);

        // 判断用户是否存在
        if (!user) {
            this.ctx.body = {
                code: 404,
                message: '用户不存在',
            };
            return;
        }

        // 校验密码
        if (user.password !== this.ctx.helper.passwordEncoder(password)) {
            this.ctx.body = {
                code: 400,
                message: '用户密码不匹配',
            };
            return;
        }

        // 读取用户的权限菜单
        let menus = await this.ctx.service.user.readMenusByUid(user.id);

        // 读取用户的角色
        let role = await this.service.user.readRoleByUid(user.id);

        let profile = {
            uid: user.id,
            username: user.username,
            relname: user.relname,
            ...role,
        };

        // 将用户相关信息也保存到 token 中
        let token = this.ctx.helper.genToken(profile);

        // 登录
        this.ctx.body = {
            code: 200,
            data: {
                token,
                menus,
                profile,
            },
            message: '登录成功',
        };
    }

    /**
     * 老师创建学生，并分配角色
     */
    async addStudent() {
        // 解构参数
        const { relname, rid } = this.ctx.request.body;

        // 是否填写名称
        if (!relname) {
            this.ctx.body = {
                code: 400,
                message: '请填写学生姓名',
            };
            return;
        }

        // 是否选择身份
        if (!rid) {
            this.ctx.body = {
                code: 400,
                message: '请选择学生身份：学生 or 学委？',
            };
            return;
        }

        // 只能分配指定角色：学委、学生
        if (isNaN(rid) && (rid = parseInt(rid)) && (rid !== 2 || rid !== 3)) {
            this.ctx.body = {
                code: 400,
                message: '学生身份只能是：学委或学生',
            };
            return;
        }

        // 将学生姓名转成拼音，用于用户名登录
        const username = this.ctx.helper.getCharFromChinese(relname);

        // 判断该账号是否已存在
        const user = await this.service.user.readByUsername(username);
        if (user) {
            this.ctx.body = {
                code: 403,
                message: `该学生对应的拼音账户：${username} 已存在`,
            };
            return;
        }

        // 添加该学生用户
        let res = await this.service.user.create({
            username,
            password: this.ctx.helper.passwordEncoder('111111'),
            relname,
        });
        if (res.affectedRows !== 1) {
            this.ctx.body = {
                code: 500,
                message: '学生添加失败',
            };
            return;
        }

        // 保存学生身份
        res = await this.service.user.saveRole({ uid: res.insertId, rid });
        if (res.affectedRows !== 1) {
            this.ctx.body = {
                code: 200,
                message: '学生添加失败，请稍后再试',
            };
            return;
        }

        // 返回成功响应
        this.ctx.body = {
            code: 200,
            message: '学生添加成功',
        };
    }

    /**
     * 获取所有学生列表
     */
    async getStudentList() {
        // 查询参数
        const res = await this.service.user.readStuListByQuery(this.ctx.query);
        this.ctx.body = {
            code: 200,
            data: res,
            message: '获取学生列表成功',
        };
    }

    async deleteStudent() {
        // 解构参数
        const { id } = this.ctx.params;
        // 删除
        await this.service.user.destroy(id);
        this.ctx.body = {
            code: 204,
            message: '删除成功',
        };
    }
}

module.exports = UserController;
